const tokenManager = require('./tokenManager');

/**
 * 服务器基础URL
 * 根据环境配置不同的API地址
 */
const BASE_URL = 'https://api.xingtu.edu.cn/v1';

/**
 * API请求封装模块
 */
const request = {
  /**
   * 发送请求
   * @param {Object} options - 请求配置
   * @param {string} options.url - 接口地址
   * @param {string} options.method - 请求方法
   * @param {Object} options.data - 请求数据
   * @param {boolean} options.auth - 是否需要带认证信息，默认true
   * @param {boolean} options.loading - 是否显示loading，默认false
   * @param {string} options.loadingText - loading提示文本
   * @param {Object} options.header - 额外的请求头
   * @returns {Promise} - 请求Promise
   */
  async request(options) {
    const {
      url,
      method = 'GET',
      data = {},
      auth = true,
      loading = false,
      loadingText = '加载中...',
      header = {}
    } = options;
    
    // 显示loading
    if (loading) {
      wx.showLoading({
        title: loadingText,
        mask: true
      });
    }
    
    // 处理请求头
    let headers = {
      'Content-Type': 'application/json',
      ...header
    };
    
    // 添加认证信息
    if (auth) {
      const authHeader = tokenManager.getAuthHeader();
      headers = { ...headers, ...authHeader };
    }
    
    return new Promise((resolve, reject) => {
      wx.request({
        url: url.startsWith('http') ? url : `${BASE_URL}${url}`,
        method,
        data,
        header: headers,
        success: async (res) => {
          if (loading) wx.hideLoading();
          
          const { statusCode, data: responseData } = res;
          
          // 请求成功
          if (statusCode >= 200 && statusCode < 300) {
            resolve(responseData.data || responseData);
            return;
          }
          
          // 认证失败处理
          if (statusCode === 401) {
            // 如果是刷新token的请求失败，直接返回错误
            if (url.includes('/auth/refresh')) {
              reject(responseData);
              return;
            }
            
            try {
              // 尝试刷新token
              await tokenManager.refreshToken();
              
              // 刷新成功，重试原请求
              const newResult = await this.request(options);
              resolve(newResult);
            } catch (error) {
              // 刷新token失败，需要重新登录
              reject(error);
              
              wx.showModal({
                title: '登录提示',
                content: '登录状态已过期，请重新登录',
                showCancel: false,
                success: () => {
                  // 跳转到登录页面
                  wx.navigateTo({
                    url: '/pages/login/login'
                  });
                }
              });
            }
            return;
          }
          
          // 处理404错误
          if (statusCode === 404) {
            // 如果是获取用户资料的请求，返回空对象而不是错误
            if (url.includes('/user/profile') || url.includes('/user/student-profile')) {
              console.log('用户资料不存在，返回空对象');
              resolve({});
              return;
            }
          }
          
          // 其他错误状态
          reject(responseData || { code: statusCode, message: '请求失败' });
        },
        fail: (err) => {
          if (loading) wx.hideLoading();
          reject({
            code: -1,
            message: '网络连接失败，请检查网络设置',
            error: err
          });
        }
      });
    });
  },
  
  /**
   * GET请求
   * @param {string} url - 接口地址
   * @param {Object} data - 请求参数
   * @param {Object} options - 其他配置
   * @returns {Promise} - 请求Promise
   */
  get(url, data = {}, options = {}) {
    return this.request({
      url,
      method: 'GET',
      data,
      ...options
    });
  },
  
  /**
   * POST请求
   * @param {string} url - 接口地址
   * @param {Object} data - 请求数据
   * @param {Object} options - 其他配置
   * @returns {Promise} - 请求Promise
   */
  post(url, data = {}, options = {}) {
    return this.request({
      url,
      method: 'POST',
      data,
      ...options
    });
  },
  
  /**
   * PUT请求
   * @param {string} url - 接口地址
   * @param {Object} data - 请求数据
   * @param {Object} options - 其他配置
   * @returns {Promise} - 请求Promise
   */
  put(url, data = {}, options = {}) {
    return this.request({
      url,
      method: 'PUT',
      data,
      ...options
    });
  },
  
  /**
   * DELETE请求
   * @param {string} url - 接口地址
   * @param {Object} data - 请求数据
   * @param {Object} options - 其他配置
   * @returns {Promise} - 请求Promise
   */
  delete(url, data = {}, options = {}) {
    return this.request({
      url,
      method: 'DELETE',
      data,
      ...options
    });
  },
  
  /**
   * 上传文件
   * @param {string} url - 上传地址
   * @param {string} filePath - 文件路径
   * @param {string} name - 文件对应的key
   * @param {Object} formData - 附加的表单数据
   * @param {Object} options - 其他配置
   * @returns {Promise} - 上传Promise
   */
  uploadFile(url, filePath, name = 'file', formData = {}, options = {}) {
    const { loading = true, auth = true, header = {} } = options;
    
    if (loading) {
      wx.showLoading({
        title: '上传中...',
        mask: true
      });
    }
    
    // 处理请求头
    let headers = { ...header };
    
    // 添加认证信息
    if (auth) {
      const authHeader = tokenManager.getAuthHeader();
      headers = { ...headers, ...authHeader };
    }
    
    return new Promise((resolve, reject) => {
      const uploadTask = wx.uploadFile({
        url: url.startsWith('http') ? url : `${BASE_URL}${url}`,
        filePath,
        name,
        formData,
        header: headers,
        success: (res) => {
          if (loading) wx.hideLoading();
          
          // 微信uploadFile的返回数据是字符串，需要转为对象
          const data = res.data ? JSON.parse(res.data) : {};
          
          if (res.statusCode >= 200 && res.statusCode < 300) {
            resolve(data.data || data);
          } else {
            reject(data || { code: res.statusCode, message: '上传失败' });
          }
        },
        fail: (err) => {
          if (loading) wx.hideLoading();
          reject({
            code: -1,
            message: '网络连接失败，请检查网络设置',
            error: err
          });
        }
      });
      
      // 上传进度回调
      if (options.onProgress) {
        uploadTask.onProgressUpdate((res) => {
          options.onProgress(res);
        });
      }
    });
  }
};

module.exports = request; 